package wci.backend.interpreter.executors;

import static wci.intermediate.icodeimpl.ICodeKeyImpl.VALUE;

import java.util.HashMap;
import java.util.List;

import wci.backend.interpreter.Executor;
import wci.intermediate.ICodeNode;
import wci.intermediate.icodeimpl.ICodeNodeTypeImpl;
import wci.intermediate.symtabimpl.SymTabKeyImpl;

/**
 * <h1>SelectExecutor</h1>
 * <p>执行CASE语句，优化版本</p>
 * <p>Copyright (c) 2009 by Ronald Mak</p>
 * <p>For instructional purposes only.  No warranties.</p>
 */
public class SelectExecutor extends StatementExecutor
{
    public SelectExecutor(Executor parent)
    {
        super(parent);
    }

    // 查找表缓存: Map键为SELECT节点，值是此节点的查找表，这个是全局的！！！执行完要清空！
    static HashMap<ICodeNode, HashMap<Object, ICodeNode>> jumpCache =
        new HashMap<ICodeNode, HashMap<Object, ICodeNode>>();
   
    public Object execute(ICodeNode node)
    {
        //缓存是否有？没有创建一个缓存项
        HashMap<Object, ICodeNode> jumpTable = jumpCache.get(node);
        if (jumpTable == null) {
            jumpTable = createJumpTable(node);
            jumpCache.put(node, jumpTable);
        }
        List<ICodeNode> selectChildren = node.getChildren();
        //计算case表达式
        ICodeNode exprNode = selectChildren.get(0);
        ExpressionExecutor expressionExecutor = new ExpressionExecutor(this);
        Object selectValue = expressionExecutor.execute(exprNode);
        // 在查找表中找Branch
        ICodeNode statementNode = jumpTable.get(selectValue);
        if (statementNode != null) {
            StatementExecutor statementExecutor = new StatementExecutor(this);
            statementExecutor.execute(statementNode);
        }
        ++executionCount; 
        return null;
    }

    /**
     * 为某一个SELECT节点根据CASE情况创建静态查找表
     * @param node SELECT节点
     * @return 查找表
     */
    private HashMap<Object, ICodeNode> createJumpTable(ICodeNode node)
    {
        HashMap<Object, ICodeNode> jumpTable = new HashMap<Object, ICodeNode>();

        // 遍历分支，将常量和语句变成查找表的某一项
        List<ICodeNode> selectChildren = node.getChildren();
        for (int i = 1; i < selectChildren.size(); ++i) {
            ICodeNode branchNode = selectChildren.get(i);
            ICodeNode constantsNode = branchNode.getChildren().get(0);
            ICodeNode statementNode = branchNode.getChildren().get(1);
            //将如1,2,3: xx的三个常量变成三个查找项
            List<ICodeNode> constantsList = constantsNode.getChildren();
            for (ICodeNode constantNode : constantsList) {
                Object value = constantNode.getAttribute(VALUE);
                if (constantNode.getType() == ICodeNodeTypeImpl.STRING_CONSTANT) {
                    value = ((String) value).charAt(0);
                }
                jumpTable.put(value, statementNode);
            }
        }
        return jumpTable;
    }
    public static void clearCache()
    {
    	for (HashMap<Object, ICodeNode>  cache_entry : jumpCache.values()){
    		cache_entry.clear();
    	}
    	jumpCache.clear();
    }
}
